package mdt;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;

//Code for the dokumentation
/*
 {label:usage}
 
 # Usage #
 
 mdt input-files [options]
 */

/*
 {label:options}
 
 # Command Line Options #
 
   * -? Displays all options
   * -o Specifies the output directory
   * -c Selects a stylesheet. This file is copied to the output directory
   * -cntop Creates a navigation bar on top of each side
   * -cnleft Creates a navigation bar on the left side of each page
   * -BB Inserts html code at the beginning of the body
   * -AA Inserts html code at the end of the body
   
 All other options are forwarded to pandoc
 */


public class MainClass
{
	public static void main(String[] args)
	{
		ArrayList<String> inputFiles = new ArrayList<String>();
		File output = null;
		String popt = "";
		String navStyleSheet = "";
		ArrayList<File> styleSheetPath = new ArrayList<File>();
		boolean createIndex = false;
		File imgFolder = null;
		String appendAfter = " ", appendAfterInner = " ";
		String appendBefore = " ", appendBeforeInner = " ";

		// Parse Inputfiles
		int j = 0;
		while (j < args.length && !args[j].startsWith("-"))
		{
			inputFiles.add(args[j]);
			j++;
		}

		// Parse Options
		for (int i = j; i < args.length; i++)
		{
			String arg = args[i];

			if (arg.equals(Configuration.OptionShowOptions)) // Display all
																// options
			{
				System.out.println("Syntax: mtd input-files [...] [options]");
				System.out.println();
				System.out.println("   " + Configuration.OptionShowOptions + "\tDisplays all options");
				System.out.println("   " + Configuration.OptionOutput + "\tSpezifies the output folder");
				System.out.println("   " + Configuration.OptionStylesheet + "\tSpezifies the stylesheet. This file is copied to the output folder.");
				System.out.println("   " + Configuration.OptionCreateIndexTop + "\tCreates a navigationbar on top of each page.");
				System.out.println("   " + Configuration.OptionCreateIndexLeft + "\tCreates a navigationbar on the left side of each page.");
				System.out.println("   " + Configuration.OptionHeaderBefore + "\tInserts html code before every other html in the body of the output file.");
				System.out.println("   " + Configuration.OptionAppendAfter + "\tInserts html code after every other html in the body of the output file.");
				System.out.println("   " + "-other" + "\tAll other options are parsed to pandoc");
				System.exit(0);
			}
			else if (arg.equals(Configuration.OptionOutput))
			{
				if (i + 1 >= args.length)
				{
					System.out.println("-o: No path given");
					System.exit(-1);
				}
				output = new File(args[i + 1]);
				i++;
			}
			else if (arg.equals(Configuration.OptionStylesheet))
			{
				File newStyleSheet = new File(args[i + 1]); 
				styleSheetPath.add(newStyleSheet); 
				i++;
				popt += " -c ./" + newStyleSheet.getName();
			}
			else if (arg.equals(Configuration.OptionCreateIndexLeft))
			{
				createIndex = true;
				navStyleSheet = "nav.css";
			}
			else if (arg.equals(Configuration.OptionCreateIndexTop))
			{
				createIndex = true;
				navStyleSheet = "nav_top.css";
			}
			else if (arg.equals(Configuration.OptionHeaderBefore))
			{
				appendBefore += "-B " + args[i+1];
				i++;
			}
			else if (arg.equals(Configuration.OptionAppendAfter))
			{
				appendAfter += "-A " + args[i+1];
				i++;
			}
			else if (arg.equals(Configuration.OptionHeaderNormal))
			{
				appendBeforeInner += "-B " + args[i+1];
				i++;
			}
			else if (arg.equals(Configuration.OptionAppendNormal))
			{
				appendAfterInner += "-A " + args[i+1];
				i++;
			}
			else
			// Not a recognized options so it must be for pandoc
			{
				popt += " " + arg;
			}
		}

		if (output == null)
		{
			System.out.println("No output folder specified. Use the -o option!");
			System.exit(-1);
		}
		else if (output.exists() && !output.isDirectory())
		{
			System.out.println("Output is not a folder or does not exist");
			System.exit(-1);
		}
		else
		{
			if (!output.exists())
				output.mkdirs();

			imgFolder = new File(output.getAbsolutePath() + "/mdt_img");
			if (imgFolder.exists())
			{
				deleteDirectory(imgFolder);
				imgFolder.delete();
			}
			imgFolder.mkdir();
		}

		// Copy StyleSheet
		for (File f : styleSheetPath)
			CopyFile(f, output);

		// Copy temporary header and footer
		if (createIndex)
		{
			CopyFromRessource("mdt/nav_head.html", output + "/mdt_nav_head.html");
			CopyFromRessource("mdt/nav_end.html", output + "/mdt_nav_end.html");

			if (!new File(output + "/mdt_nav.css").exists())
				CopyFromRessource("mdt/" + navStyleSheet, output + "/mdt_nav.css");

			// Copy jquery
			CopyFromRessource("mdt/jquery.min.js", output + "/jquery.min.js");

			// Build navigation
			String listText = "";

			for (String inputFile : inputFiles)
			{
				File outputFile = new File(inputFile);
				String outputName = outputFile.getName();
				if (outputName.indexOf('.') != -1)
				{
					outputName = outputName.substring(0, outputName.indexOf('.'));
				}
				listText += "<li><a href=\"" + outputName + ".html\">" + outputName + "</a></li>";
			}

			CopyNavHTML("mdt/nav.html", output + "/mdt_nav.html", listText);

			// Pass to pandoc
			popt = appendAfterInner + " -H " + output + "/mdt_nav_head.html -A " + output + "/mdt_nav_end.html" + appendAfter + " " + popt + " " + appendBefore + " -B " + output + "/mdt_nav.html" + appendBeforeInner;
		}
		else
		{
			CopyFromRessource("mdt/nav_end.html", output + "/mdt_nav_end.html");
			CopyFromRessource("mdt/nonav.html", output + "/mdt_nonav.html");
			
			popt = appendAfterInner + " -A " + output + "/mdt_nav_end.html" + appendAfter + " " + popt + " " + appendBefore + " -B " + output + "/mdt_nonav.html" + appendBeforeInner;
		}

		// Parse all input files
		String tmpFile = "";

		for (String inputFile : inputFiles)
		{
			try
			{
				MarkupParser markdownParser = new MarkupParser(output);
				
				// ###################################################
				// Include custom parsers here
				// ###################################################
				
				markdownParser.RegisterTag(new ExampleRedParser());
				markdownParser.RegisterTag(new ExampleYellowParser());
				markdownParser.RegisterTag(new DocumentationParser());
				
				// ###################################################
				// End of custom parser
				// ###################################################
				
				tmpFile = markdownParser.Parse(inputFile);
			}
			catch (Exception e)
			{
				System.out.println("Error while parsing " + inputFile);
				System.out.println(e.getMessage());
				//e.printStackTrace();
				break;
			}

			// Call Pandoc
			try
			{
				File outputFile = new File(inputFile);
				String outputName = outputFile.getName();
				if (outputName.indexOf('.') != -1)
				{
					outputName = outputName.substring(0, outputName.indexOf('.'));
				}
				PandocCompiler.Compile(tmpFile, output.getAbsolutePath() + "/" + outputName + ".html", popt);
			}
			catch (CompilerException e)
			{
				System.out.println("Error while compiling " + tmpFile.replace(".tmp", ""));
				System.out.println(e.getMessage());
			}

		/*	File f = new File(tmpFile);
		if (!f.delete())
				System.out.println("Unabel to delete temporary file.");*/
		}
		
		//Delete image folder if empty
		if (imgFolder.list().length == 0)
			imgFolder.delete();

		// Delete temporary Files
		if (createIndex)
		{
			new File(output + "/mdt_nav_head.html").delete();
			new File(output + "/mdt_nav_end.html").delete();
			new File(output + "/mdt_nav.html").delete();
		}
		else
		{
			new File(output + "/mdt_nav_end.html").delete();
			new File(output + "/mdt_nonav.html").delete();
		}
	}

	private static void CopyFile(File _filePath, File _outputDir)
	{
		// Copy Stylesheet
		if (_filePath != null)
		{
			// Copy
			BufferedInputStream bis;
			try
			{
				bis = new BufferedInputStream(new FileInputStream(_filePath));
				BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(_outputDir + "/" + _filePath.getName()));

				int theChar;
				while ((theChar = bis.read()) != -1)
				{
					bos.write(theChar);
				}
				bos.close();
				bis.close();

			}
			catch (FileNotFoundException e)
			{
				System.out.println("File not found: " + _filePath.getAbsolutePath());
				System.exit(-1);
			}
			catch (IOException e)
			{
				System.out.println("Error while copying file: " + _filePath.getAbsolutePath());
				System.out.println(e.getMessage());
				System.exit(-1);
			}
		}
	}

	private static void CopyFromRessource(String _ressource, String _output)
	{
		try
		{
			InputStream jQueryInput = ClassLoader.getSystemResourceAsStream(_ressource);
			BufferedInputStream bis = new BufferedInputStream(jQueryInput);
			BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(_output));
			int theChar;
			while ((theChar = bis.read()) != -1)
			{
				bos.write(theChar);
			}
			bos.close();
			bis.close();
		}
		catch (IOException ioe)
		{
			System.out.println("Failed to copy Ressource");
			System.out.println(ioe.getMessage());
		}
	}

	private static void CopyNavHTML(String _ressource, String _output, String _list)
	{
		try
		{
			InputStream jQueryInput = ClassLoader.getSystemResourceAsStream(_ressource);
			BufferedInputStream bis = new BufferedInputStream(jQueryInput);
			BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(_output));

			byte[] data = new byte[bis.available()];
			bis.read(data);
			String content = new String(data);

			content = content.replace("<!--LISTINSERT-->", _list);

			bos.write(content.getBytes());

			bos.close();
			bis.close();
		}
		catch (IOException ioe)
		{
			System.out.println("Failed to copy Ressource");
			System.out.println(ioe.getMessage());
		}
	}

	static public void deleteDirectory(File path)
	{
		if (path.exists())
		{
			File[] files = path.listFiles();
			for (int i = 0; i < files.length; i++)
			{
				if (files[i].isDirectory())
				{
					deleteDirectory(files[i]);
				}
				else
				{
					files[i].delete();
				}
			}
		}
	}
}
